{-# OPTIONS -Wall #-}

module Demo01 where

import HydroChecks
import HydroConfig
import HydroData

import ConfigCheck.Checker

import Control.Applicative

import qualified Data.IntMap as IM

import Text.Printf


interpolate1 :: PrintfArg a => String -> a -> String
interpolate1 fmt a = printf fmt a


-- | TEMP - projector...
--
-- This could be used for a faster /checklast/ if we are using
-- IntMap.
--
imlast :: IM.IntMap a -> Maybe a
imlast im = if IM.null im then Nothing else (Just . snd) $ IM.findMax im


-- Doodles here are how to write checkers without the
-- Checker machinery.

unit_is_meters_ :: HydroConfig -> Bool
unit_is_meters_ (HydroConfig _ _ s) = sensor_original_units s == UNIT_METERS



empty_dist_gt_span_ :: HydroConfig -> Bool
empty_dist_gt_span_ (HydroConfig _ _ s) = 
    sensor_empty_distance s > sensor_span s


withSensor :: (Sensor -> a) -> HydroConfig -> a
withSensor f (HydroConfig _ _ s) = f s

-- | Direct pattern matching in this case does not improve on 
-- using accessors...
-- 
-- (Config datatypes are expected to have many fields)
--
span_lt_empty_dist_1 :: HydroConfig -> Bool
span_lt_empty_dist_1 = withSensor fn
  where
    fn (Sensor { sensor_span = s, sensor_empty_distance = e}) = s < e


-- | Applicatively using field accessors is quite nice 
-- 
-- /It looks like Haskell!/
--
span_lt_empty_dist_2 :: HydroConfig -> Bool
span_lt_empty_dist_2 = withSensor fn
  where
    fn = (<) <$> sensor_span <*> sensor_empty_distance

{-

-- Exercise - it is possible to define onlyJust with onlyif
-- This means users can define ther own only__ functions. 
--
-- It also implies onlyif should be exposed.
--
onlyJust2 :: CheckFun u -> CheckFun (Maybe u)
onlyJust2 ma = ask >>= \a -> case a of 
    Just _ -> focus fromJust ma
    Nothing -> throwError "onlyJust2"

onlyJust3 :: CheckFun u -> CheckFun (Maybe u)
onlyJust3 ma = selftest isJust >> focus fromJust ma

-- ...

-}

-- Note should probably have /check groups/ e.g. for Loss-of-echo

all_resources :: [HydroConfig]
all_resources = bad_example : good_resources

good_resources :: [HydroConfig]
good_resources = [ ai_001, an_001, be_001, be_002, br_001
                 , ca_001, gr_001, li_001
                 , me_001, no_001, pe_001, po_001, sc_001, st_001, st_002 
                 , va_001
                 ]

bad_resources :: [HydroConfig]
bad_resources = [ bad_example ]


-- Need better error messages! And a way to report index of failing relay.


demo01 :: IO ()
demo01 = mapM_ (putStrLn . printReportSimple . runGroups groups) bad_resources
  where
    groups = [ quickstart_group
             , relay_group
             , pumpcontrol_group
             , loe_group
             ]

test01 = putStrLn $ checker_description material_liquid_or_nothing